Skip to main content

Setting up CI CD for Developers

This tutorial will guide you through the steps to set up a project on the ABAIR CI/CD pipeline. As an example, it uses a node application with the name ABAIR_APP_X.

Prerequisites:

  1. Server:

    • You have a key for your project to SSH into the services VM.
    • An Admin has set up a directory for your project with a deployment script.
  2. Github:

  3. Docker:

    • You have Docker installed on your local machine.
    • You have a Dockerfile in the root of your project that successfully builds an image of your application.
    • This image can be run locally using Docker and accessed over the specified open port.
    • You have been given the Docker Password for the registry.

Steps

1. Add CI/CD Github Actions to your project

Create a .github/workflows/ folder in the root of your project and add the following 2 files

ci.yml

name: Node.js CI

on:
pull_request:
branches: [main]

jobs:
build:
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v3
- name: Use Node.js LTS
uses: actions/setup-node@v3
with:
node-version: 18.16.0
- run: |
npm i

cd.yml

name: Publish Docker image

on:
push:
branches:
- main

jobs:
push_to_registry:
name: Push Docker image to Docker Registry
runs-on: ubuntu-latest
environment: prod
steps:
- name: Check out the repo
uses: actions/checkout@v2

- name: Log in to Docker Hub
uses: docker/login-action@f054a8b539a109f9f41c372932f1ae047eff08c9
with:
registry: ${{ vars.DOCKER_REGISTRY }}
username: ${{ vars.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}

- name: Extract metadata (tags, labels) for Docker
id: meta
uses: docker/metadata-action@v4
with:
images: registry.abair.ie:5000/${{ vars.PROJECT_NAME }}

- name: Build and push Docker image
uses: docker/build-push-action@v3
with:
context: .
push: true
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
update_ssh:
name: Update running software
needs: "push_to_registry"
runs-on: ubuntu-latest
environment: prod
steps:
- name: executing remote ssh commands using password
uses: appleboy/ssh-action@master
with:
host: ${{ vars.HOST }}
username: ${{ vars.USERNAME }}
key: ${{ secrets.SSH_PRIVATE_KEY }}
port: ${{ vars.PORT }}
script: bash ${{ vars.DEPLOY_SCRIPT_PATH }}

2. Generate SSH Private Key

Recommended: Use the generate-ssh-key.sh script which automates the steps below.

  1. Sign into the Services VM as a sudo user.
  2. Sign into the services account using sudo su services.
  3. Run the following command to generate the SSH key. Make sure to replace ABAIR_APP_X with the name of your app.
ssh-keygen -t ed25519 -a 100 \
-C "ABAIR_APP_X Github Action" \
-f ~/.ssh/ABAIR_APP_X_ed25519 \
-N ""
  1. Add the public key to authorized_keys so the Services VM accepts connections using this key:
cat ~/.ssh/ABAIR_APP_X_ed25519.pub >> ~/.ssh/authorized_keys
  1. Copy the private key contents to the GitHub prod environment secrets as SSH_PRIVATE_KEY:
cat ~/.ssh/ABAIR_APP_X_ed25519

Copy the entire output (including -----BEGIN OPENSSH PRIVATE KEY----- and -----END OPENSSH PRIVATE KEY-----).

3. Create Environment and Set Secrets/Variables

On the Github page for ABAIR_APP_X:

3.1 Create the prod Environment

  1. Navigate to SettingsEnvironments
  2. Click New environment
  3. Name it prod and click Configure environment

3.2 Add Environment Secrets

In the prod environment settings, under Environment secrets, add:

NameValue
DOCKER_PASSWORD(provided by Admin)
SSH_PRIVATE_KEYPrivate SSH key from the services user in the Services VM

3.3 Add Environment Variables

In the prod environment settings, under Environment variables, add:

NameValue
PROJECT_NAMEABAIR_APP_X
DOCKER_REGISTRYregistry.abair.ie:5000
DOCKER_USERNAMEadmin
HOSTsrv.abair.ie
USERNAMEservices
PORT22102
DEPLOY_SCRIPT_PATH/home/services/ABAIR_APP_X/deploy-ABAIR_APP_X.sh

4. Deploy Script

Add the following deploy script to the base of your project for reference. It will be copied by Admin to the Services VM

deploy-ABAIR_APP_X.sh

docker stop ABAIR_APP_X
docker rm ABAIR_APP_X

docker login 10.0.0.2:5000 -u admin -p {see elsewhere}
docker rmi 10.0.0.2:5000/ABAIR_APP_X:main
docker pull 10.0.0.2:5000/ABAIR_APP_X:main

docker run -t -d -p port:port --restart always --name project-name 10.0.0.2:5000/ABAIR_APP_X:main

FAQ

The CI/CD Fails when I add supabase to my project

Solution

  1. Add the following to the Dockerfile of your project before RUN npm run build
ARG NEXT_PUBLIC_SUPABASE_URL
ARG NEXT_PUBLIC_SUPABASE_ANON_KEY
ENV NEXT_PUBLIC_SUPABASE_URL=$NEXT_PUBLIC_SUPABASE_URL
ENV NEXT_PUBLIC_SUPABASE_ANON_KEY=$NEXT_PUBLIC_SUPABASE_ANON_KEY
  1. Update the cd.yml file to include the following in the "Build and push Docker image" step (the failing step).
build-args: |
NEXT_PUBLIC_SUPABASE_URL=${{ vars.NEXT_PUBLIC_SUPABASE_URL }}
NEXT_PUBLIC_SUPABASE_ANON_KEY=${{ vars.NEXT_PUBLIC_SUPABASE_ANON_KEY }}
  1. In the GitHub project:
    1. Go to: Settings -> Environments -> prod -> Environment variables
    2. Add the supabase url (NEXT_PUBLIC_SUPABASE_URL) and anon key (NEXT_PUBLIC_SUPABASE_ANON_KEY) variables. These can be found in the supabase project settings.

Failing to authorize using publickey

Follow this carefully.

  • Make sure your private SSH key is pasted correctly into the GitHub prod environment secrets as SSH_PRIVATE_KEY. You must copy all contents of the file.
  • Make sure that your ssh key file is named correctly (ABAIR_APP_X_ed25519).
  • Make sure that your public ssh key is added to authorized keys.